package kr.ac.kongju.gedl.cmmn.menu;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Iterator;
import java.util.LinkedHashMap;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import kr.ac.kongju.gedl.cmmn.web.SpringContextManager;

import org.apache.xpath.XPathAPI;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;



public class MenuManager {

	private static MenuManager manager;

	private LinkedHashMap<String, MenuLevelVO> menuList;
	
	public LinkedHashMap<String, MenuLevelVO> getMenuList() {
		return menuList;
	}

	public void setMenuList(LinkedHashMap<String, MenuLevelVO> menuList) {
		this.menuList = menuList;
	}

	
	public static MenuManager getInstance() {
		if(manager == null) {
			synchronized(MenuManager.class) {
				manager = new MenuManager();
			}
		}

		return manager;
	}

	private MenuManager() {
		init();
	}

	public void init() {
		try {
			menuList = new LinkedHashMap<String, MenuLevelVO>();
			InputStream is = SpringContextManager.getInstance().getContext().getResource("classpath:/config/properties/menu.xml").getInputStream();
			DocumentBuilderFactory docBF = DocumentBuilderFactory.newInstance();
			DocumentBuilder docBuilder = (DocumentBuilder) docBF.newDocumentBuilder();
			InputSource inSource = new InputSource(new InputStreamReader(is, "UTF-8"));
			Document menuDoc = docBuilder.parse(inSource);
			Element root = menuDoc.getDocumentElement();
			int levelCount = 1;
			NodeList nodeList = XPathAPI.selectNodeList(root, "/menuInfo/level"+levelCount);

			for(int i = 0; i < nodeList.getLength(); i++) {
				Node level = nodeList.item(i);
				MenuLevelVO menuLevelVO = new MenuLevelVO();
				NamedNodeMap attr = level.getAttributes();
				menuLevelVO.setMenuId(attr.getNamedItem("id").getNodeValue());
				menuLevelVO.setMenuNm(attr.getNamedItem("name").getNodeValue());
				menuLevelVO.setUrl(attr.getNamedItem("url").getNodeValue());
				
				setSubMenuList(level, levelCount+1, menuLevelVO);
				menuList.put(menuLevelVO.getMenuId(), menuLevelVO);
			}
			

		} catch(Exception ex) {
			ex.printStackTrace();
		}
	}

	public void setSubMenuList(Node node, int levelCount, MenuLevelVO menuLevelVO) throws Exception{
		NodeList nodeList = XPathAPI.selectNodeList(node, "./level"+levelCount);
		if(nodeList != null && nodeList.getLength() > 0) {
			menuLevelVO.setSubMenulist(new LinkedHashMap<String, MenuLevelVO>());
		}
		for(int i = 0; i < nodeList.getLength(); i++) {
			Node level = nodeList.item(i);
			MenuLevelVO subMenuLevelVO = new MenuLevelVO();
			NamedNodeMap attr = level.getAttributes();
			subMenuLevelVO.setMenuId(attr.getNamedItem("id").getNodeValue());
			subMenuLevelVO.setMenuNm(attr.getNamedItem("name").getNodeValue());
			subMenuLevelVO.setUrl(attr.getNamedItem("url").getNodeValue());
			subMenuLevelVO.setParent(menuLevelVO);
			setSubMenuList(level, levelCount+1, subMenuLevelVO);
			menuLevelVO.addSubMenulist(subMenuLevelVO.getMenuId(), subMenuLevelVO);
		}
	}
	
	
	public MenuLevelVO getTopMenu(MenuLevelVO menuLevel) {
		MenuLevelVO topMenu = new MenuLevelVO();
		
		if(menuLevel.getParent() != null) {
			topMenu = findTopMenu(menuLevel.getParent());
		} else {
			topMenu = menuLevel;
		}
		
		return topMenu;
	}
	
	public MenuLevelVO findTopMenu(MenuLevelVO menuLevel) {
		MenuLevelVO returnVal = null;
		
		if(menuLevel.getParent() != null) {
			returnVal = findTopMenu(menuLevel.getParent());
		} else {
			returnVal = menuLevel;
		}
		
		return returnVal;
	}
	
	public MenuLevelVO getMenu(String menuId) {
		return menuList.get(menuId);
	}
	
	public MenuLevelVO getCurrentMenu(String url) {
		MenuLevelVO returnMenuVO = null;
		Iterator<String> key = menuList.keySet().iterator();
		while(key.hasNext() && returnMenuVO == null) {
			MenuLevelVO menuLevelVO = menuList.get(key.next());
			if(url.indexOf(menuLevelVO.getUrl()) > -1) {
				returnMenuVO = menuLevelVO;
			} else {
				if(menuLevelVO.getSubMenulist() != null && menuLevelVO.getSubMenulist().size() > 0) {
					returnMenuVO = getCurrentMenu(menuLevelVO.getSubMenulist(), url);
				}
			}
		}
		return returnMenuVO;
	}
	
	public MenuLevelVO getCurrentMenu(LinkedHashMap<String, MenuLevelVO> menuList, String url) {
		MenuLevelVO returnMenuVO = null;
		Iterator<String> key = menuList.keySet().iterator();
		while(key.hasNext() && returnMenuVO == null) {
			MenuLevelVO menuLevelVO = menuList.get(key.next());
			if(url.indexOf(menuLevelVO.getUrl()) > -1) {
				returnMenuVO = menuLevelVO;
			} else {
				if(menuLevelVO.getSubMenulist() != null && menuLevelVO.getSubMenulist().size() > 0) {
					returnMenuVO = getCurrentMenu(menuLevelVO.getSubMenulist(), url);
				}
			}
			
		}
		
		return returnMenuVO;
	}
	
	
	
}
